#ifndef __VIEW_FRUSTUM_HPP__
#define __VIEW_FRUSTUM_HPP__

#include "../Mathematics/MVector3D.hpp"

class BoundingVolume;
class BoundingSphere;
class BoundingBox;

typedef enum eFrustumCollisionStatus
{
	OUTSIDE,
	INSIDE,
	INTERSECTING

} FRU_COLL_STAT;

typedef enum ePlanes
{
	NEAR_PLANE,
	FAR_PLANE,
	LEFT_PLANE,
	RIGHT_PLANE,
	TOP_PLANE,
	BOTTOM_PLANE,

	NUM_PLANES

} CULL_PLANES;

class CullingPlane
{
public:
	CullingPlane() {};
	~CullingPlane() {};

	void  setCenter(MVector3D& center);
	void  setNormal(MVector3D& normal);

	const MVector3D&  getNormal() const;
	const MVector3D&  getCenter() const;
	//bool              isOutside(BoundingVolume* pBV);
	bool              isOutside(BoundingSphere* pBSphere);
	//bool              isOutside(BoundingBox* pBBox);
	bool              isOutside(MVector3D& point);

private:
	float  distance(BoundingSphere* pBSphere);
	float  distance(BoundingBox* pBBox); //should check with points for BB
	float  distance(MVector3D& point);

	MVector3D m_normal;
	MVector3D m_center;
};

class ViewFrustum
{
public:
	//ViewFrustum();
	ViewFrustum(MVector3D pos, MVector3D target, MVector3D up, float& fNearPlane,  float& fFov, float& fFarPlane, float fRatio =0.0f);
	~ViewFrustum();

	void  invalidateFrustum(MVector3D pos, MVector3D target, MVector3D up, float& fNearPlane,  float& fFov, float& fFarPlane, float& fRatio);
	FRU_COLL_STAT  isInFrustum(BoundingSphere* pBV);//(BoundingVolume* pBV);
	FRU_COLL_STAT  isInFrustum(BoundingBox* pBV);

private:
	CullingPlane*  m_pPlanes;

	float m_fFOV;
	float m_fRatio;

	float m_fNearPlaneDist;
	float m_fNearPlaneWidth;
	float m_fNearPlaneHeight;

	float m_fFarPlaneDist;
	float m_fFarPlaneWidth;
	float m_fFarPlaneHeight;

	MVector3D  m_camPos;
	MVector3D  m_camViewRay; //normalized
	MVector3D  m_camUp; //normalized
	MVector3D  m_camRight; //normalized: up x view
};

#endif //__VIEW_FRUSTUM_HPP__

//EOF
